<?php
require_once('JankFileException.php');
/**
 * 
 * The JankParser class is extended by any application using JankFramework. This
 * base class provides the basic keyword-replacing functionality of the parser. 
 * Any child classes of JankParser must provide application-specific methods for
 * parsing the keywords defined for the application's templates.
 * 
 * @author Rick Hutcheson
 * @version 0.1
 */
abstract class JankParser {
    // TODO: Remove these as private fields unless we need them for some extension.
    private $file;
    private $filename;
    
    private $template;
    private $keywords;
    
    /**
     * An array of values which differ from page to page. These can be set
     * within an action.
     */
    protected $values;
    
    
    /**
     * Reads all keywords from the "keywords" file defined for the particular 
     * application, returning them as an array.
     */
    private function getKeywords() {
        $keyFile= fopen(TEMPLATE_KEYWORDS, 'r');
        if(!$keyFile) {
            throw new JankFileException(
                                    "Keyword file must exist and be readable.");
        }
        
        $keyString = fread($keyFile, filesize(TEMPLATE_KEYWORDS));
        $this->keywords = explode(PHP_EOL, $keyString);
    }
    
    /**
     * 
     * Parses all keywords contained in its template argument, replacing them 
     * with business logic. Note that in order to parse these keywords, it will 
     * call methods which must be implemented in the child classes of this 
     * object. This function, before parsing, will test whether the template
     * file is readable. If it is not, it will throw a JankFileException.
     * 
     * @param string $filename
     *  The string representation of the full file path to the initialized 
     *  template.
     * @param type array $values
     *  Values which are important to the template, such as the section title, 
     *  etc.
     * 
     * @throws JankFileException
     */
    public function parse($filename, $values = array()) {
        $this->values = $values;
        
        $this->filename = $filename;
        
        $this->file = fopen($this->filename, 'r');
        if (!$this->file) {
            throw new JankFileException("File must exist and be readable.");
        }
        
        // get application keywords.
        try {
            $this->getKeywords();
        } catch(JankFileException $jfe) {
            throw new JankFileException(
                                    "Keyword file must exist and be readable.");    
        }
        
        $existingKeywords = array();
        $neededFunction = array();
        
        $this->template = fread($this->file, filesize($this->filename));
        if (!$this->template) {
            throw new JankFileException("File must exist and be readable.");
        }
        
        $parsed = $this->template;
        foreach ($this->keywords as $keyword) {
            
            //TODO: replace with regex
            $key = "{{" . $keyword . "}}";
            
            $keyword = str_replace("_", " ", $keyword);
            $keyword = ucwords($keyword);
            $keyword = str_replace(" ", "", $keyword);
            
            
            if(strpos($this->template, $key)) {
                $existingKeywords[] = $key;  
                $function = 'parse' . ucwords($keyword);
                $neededFunctions[$key] = $function;
            }   
        }
        
        foreach($existingKeywords as $keyword) {
            $function = $neededFunctions[$keyword];
            $parsed = str_replace($keyword, $this->$function(), $parsed);
        }
        return $parsed;
    }
}

